#include <54func.h>
int main(int argc,char *argv[])
{
    //./ 4_server 12.168.187.128 1234
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    ERROR_CHECK(sockfd,-1,"socket");
    //定义和初始化struct sockaddr_in 结构体
    //下述这段代码主要使用一个已经创建的套接字，连接到指定的服务器地址和端口，这是服务器代码，用于被动连接
    struct sockaddr_in addr;//ipv4的具体类型
    addr.sin_family = AF_INET;//设置地址族（IPV4还是IPv6）
    addr.sin_port = htons(atoi(argv[2]));//将字符串端口号转换为整数，同时在将其转换为大端序
    addr.sin_addr.s_addr = inet_addr(argv[1]);//将点分十进制的ip地址转换为网络地址
    int ret = bind(sockfd,(struct sockaddr *)&addr,sizeof(addr));//将socket与服务器ip与端口绑定
    ERROR_CHECK(ret,-1,"bind");
    listen(sockfd,50);
    
    struct sockaddr_in addrClient;//获取客户端的ip
    //addrlen：必须要赋初始值，因为在accept中直接传递的是其地址或指针
    socklen_t addrlen = sizeof(addrClient);
    //accept：返回的是一个文件描述符，原本服务器的socket文件对象是有一个发送缓冲区和一个接收缓冲区，当客户端发送connect后将两个缓冲区转变为半连接队列和全连接队列
    //因此若是想让服务器与客户端进行通信，需要在重新打开一个文件描述符，因此accept的作用就是打开一个新的socket文件对象，用于后续通信
    int netfd = accept(sockfd,(struct sockaddr *)&addrClient,&addrlen);//后面两个参数是用于去获取客户端的ip和端口号,若是不获取则填写0
    ERROR_CHECK(netfd,-1,"accept");
    printf("client ip = %s,prot = %d\n",
          inet_ntoa(addrClient.sin_addr),//将网络地址转换为点分十进制
          ntohs(addrClient.sin_port));//在输出和处理数据时，通常将其转换为主机字节序，以便于在本机上正常显示或处理
   
    char server[4096] = {0};
    ssize_t sret = recv(netfd,server,sizeof(server),0);
    ERROR_CHECK(sret,-1,"recv");
    printf("server = %s\n",server);
    sret = send(netfd,"howareyou",9,0);

    return 0;
}
